/**
 * 
 */
package com.bitBusy.manageyourriches.emailManagement;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.security.Security;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.mail.internet.MimeMultipart;
import javax.sql.DataSource;


import android.util.Log;


/**
 * @author SumaHarsha
 *
 */
public class Delivery extends javax.mail.Authenticator{
	
		private static final String MAILHOST = "mail.host";
		private static final String MAILHOSTUSED = "smtp.gmail.com";   
	    private static final String PROTOCOL = "mail.transport.protocol";
	    private static final String PROTOCOLUSED = "smtp";
	    private static final String AUTH = "mail.smtp.auth";
	    private static final String AUTHVALUE = "true";
	    private static final String PORT = "mail.smtp.port";
	    private static final String PORTUSED = "465";
	    private static final String SOCKETFACTORYPORT = "mail.smtp.socketFactory.port";
	    private static final String SOCKETFACTORYCLASS = "mail.smtp.socketFactory.class";
	    private static final String SOCKETFACTORYCLASSUSED = "javax.net.ssl.SSLSocketFactory";
	    private static final String FALLBACK = "mail.smtp.socketFactory.fallback";
	    private static final String FALLBACKVALUE = "false"; 
	    private static final String QUITWAIT = "mail.smtp.quitwait";
	    private static final String QUITWAITVALUE = "false";
	  //  private static final String TEXTPLAINFILE = "text/plain";
	    private static final String ERRORSENDING = "Exception during delivery of mail"; 
	  //  private PasswordAuthentication myAuthentication;
	    
	    private Session mySession;
	    private EmailLocal myEmail;
	    private Multipart myMultipart;
	    static {   
	        Security.addProvider(new JSSEProvider());   
	    }  

	    public Delivery(EmailLocal the_email) {   
	    	
	    	myEmail = the_email;
	    	Properties properties = new Properties();   
	    	properties.setProperty(PROTOCOL, PROTOCOLUSED);   
	    	properties.setProperty(MAILHOST, MAILHOSTUSED);   
	    	properties.put(AUTH, AUTHVALUE);   
	    	properties.put(PORT, PORTUSED);   
	    	properties.put(SOCKETFACTORYPORT, PORTUSED);   
	    	properties.put(SOCKETFACTORYCLASS, SOCKETFACTORYCLASSUSED);   
	    	properties.put(FALLBACK, FALLBACKVALUE);   
	    	properties.setProperty(QUITWAIT, QUITWAITVALUE);   
	    	mySession = Session.getDefaultInstance(properties, this);   
	    	myMultipart = new MimeMultipart();
	    	
	    }   
	    @Override
	    public PasswordAuthentication getPasswordAuthentication() {   
	        return new PasswordAuthentication(myEmail.getFromAddress(), myEmail.getFromPwd());   
	    }   
  

	    public synchronized Postman.EMAILSENTCODES deliver()throws Exception {   
	        try{
	        MimeMessage message = getMessage(); 
	       new OutForDelivery().execute(message);	
	       //Transport.send(message);
	        return Postman.EMAILSENTCODES.SUCCESS;
	        }catch(Exception e){
	        	Log.e(this.getClass().getCanonicalName(), ERRORSENDING + e);
	        	return Postman.EMAILSENTCODES.FAILURESYSEM;
	        }
	    }   

	    /**
		 * @return
		 */
	private MimeMessage getMessage() {

		MimeMessage message = new MimeMessage(mySession);
		// DataHandler handler = new DataHandler(new
		// ByteArrayDataSource(myEmail.getBody().getBytes(), TEXTPLAINFILE));
		try {
			message.setSender(new InternetAddress(myEmail.getFromAddress()));
			
			message.setSubject(myEmail.getSubject());
			// message.setDataHandler(handler);
			/*
			 * if (recipients.indexOf(',') > 0)
			 * message.setRecipients(Message.RecipientType.TO,
			 * InternetAddress.parse(recipients)); else
			 */
			message.setRecipient(RecipientType.TO,
					new InternetAddress(myEmail.getToAddress()));
			message.setSentDate(new Date());
			// setup message body
			BodyPart messageBodyPart = new MimeBodyPart();
			messageBodyPart.setText(myEmail.getBody());
			myMultipart.addBodyPart(messageBodyPart);
			addAttachment();

			message.setContent(myMultipart);
		} catch (AddressException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return message;

	}
		
		  private void addAttachment() throws Exception { 
			  if (myEmail.getFile() != null)
			  {
	            BodyPart messageBodyPart = new MimeBodyPart(); 
	            FileDataSource source = new FileDataSource(myEmail.getFile()); 
	            messageBodyPart.setDataHandler(new DataHandler(source)); 
	            messageBodyPart.setFileName(myEmail.getFile().getName()); 
	            myMultipart.addBodyPart(messageBodyPart);
			  }	
	          } 

		public class ByteArrayDataSource implements DataSource {   
	        private byte[] data;   
	        private String type;   

	        public ByteArrayDataSource(byte[] data, String type) {   
	            super();   
	            this.data = data;   
	            this.type = type;   
	        }   

	        public ByteArrayDataSource(byte[] data) {   
	            super();   
	            this.data = data;   
	        }   

	        public void setType(String type) {   
	            this.type = type;   
	        }   

	        public String getContentType() {   
	            if (type == null)   
	                return "application/octet-stream";   
	            else  
	                return type;   
	        }   

	        public InputStream getInputStream() throws IOException {   
	            return new ByteArrayInputStream(data);   
	        }   

	        public String getName() {   
	            return "ByteArrayDataSource";   
	        }   

	        public OutputStream getOutputStream() throws IOException {   
	            throw new IOException("Not Supported");   
	        }

			/* (non-Javadoc)
			 * @see javax.sql.CommonDataSource#getLogWriter()
			 */
			@Override
			public PrintWriter getLogWriter() throws SQLException {
				// TODO Auto-generated method stub
				return null;
			}

			/* (non-Javadoc)
			 * @see javax.sql.CommonDataSource#getLoginTimeout()
			 */
			@Override
			public int getLoginTimeout() throws SQLException {
				// TODO Auto-generated method stub
				return 0;
			}

			/* (non-Javadoc)
			 * @see javax.sql.CommonDataSource#setLogWriter(java.io.PrintWriter)
			 */
			@Override
			public void setLogWriter(PrintWriter arg0) throws SQLException {
				// TODO Auto-generated method stub
				
			}

			/* (non-Javadoc)
			 * @see javax.sql.CommonDataSource#setLoginTimeout(int)
			 */
			@Override
			public void setLoginTimeout(int arg0) throws SQLException {
				// TODO Auto-generated method stub
				
			}

			/* (non-Javadoc)
			 * @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
			 */
			@Override
			public boolean isWrapperFor(Class<?> arg0) throws SQLException {
				// TODO Auto-generated method stub
				return false;
			}

			/* (non-Javadoc)
			 * @see java.sql.Wrapper#unwrap(java.lang.Class)
			 */
			@Override
			public <T> T unwrap(Class<T> arg0) throws SQLException {
				// TODO Auto-generated method stub
				return null;
			}

			/* (non-Javadoc)
			 * @see javax.sql.DataSource#getConnection()
			 */
			@Override
			public Connection getConnection() throws SQLException {
				// TODO Auto-generated method stub
				return null;
			}

			/* (non-Javadoc)
			 * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
			 */
			@Override
			public Connection getConnection(String arg0, String arg1)
					throws SQLException {
				// TODO Auto-generated method stub
				return null;
			}   
	    }   
		
		

}
